package tv.accedo.achi.service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import tv.accedo.achi.dao.AchiDao;
import tv.accedo.achi.dao.BadgeDao;
import tv.accedo.achi.dao.CampDao;
import tv.accedo.achi.dao.UserDao;
import tv.accedo.achi.model.Achi;
import tv.accedo.achi.model.User;

/**
 * The business logic service of achievement relevant functionality.
 * @author Bo Liang
 *
 */
@Component
public class AchiService {

	private AchiDao achiDao; //injection
	private UserDao userDao; //injection
	private Achi achi; //injection
	private User user; //injection
	private BadgeDao badgeDao; //injection
	private CampDao campDao; //injection
	
	/**
	 * Get the specific achievement's description
	 * @param achi_sn	achievement serial number
	 * @return			JSON format achievement description
	 */
	public String getJsonAchiByAchisn(String achi_sn) {
		achi = achiDao.getAchiByAchisn(achi_sn); 
		String jsonAchi = "{achi_desc:'" + achi.getAchi_desc() 
						+ "', achi_name:'"+ achi.getAchi_name() 
						+ "', achi_score:"+ achi.getAchi_score() + "}";
		return jsonAchi; 
	}
	
	/**
	 * The function deals with the events with unlock and relevant events about badges and campaigns.
	 * @param username	user name
	 * @param achi_sn	achievement serial number
	 * @return			JSON format popup
	 */
	public String unlockAndJsonPopup(String username, String achi_sn) {		
		achi = achiDao.getAchiByAchisn(achi_sn); 
		user = userDao.getUserByUsername(username); 
		// add the achievement to user's Set
		String flag = userDao.addAchiToUser(username, achi_sn); 
		
		// if this achievement is unlocked first time by this user
		if (flag.equals("new")) {
			// add this achievement's score to user
			userDao.addScoreToUser(username, achi.getAchi_score());
			
			List<Integer> badgeIdList = new ArrayList<Integer>(); 
			badgeIdList = badgeDao.getBadgesIdByAchiId(achi.getId()); 
			
			// badges which related to this achievement, add the relevant number of badge increased
			for (Iterator<Integer> iter = badgeIdList.iterator(); iter.hasNext(); ) {
				int badge_id = iter.next(); 
				userDao.addBadgeNumToUser(username, badge_id); 
			}
			
			List<Integer> campIdList = new ArrayList<Integer>(); 
			campIdList = campDao.getCampsIdByAchiId(achi.getId()); 
			
			// campaigns which related to this achievement, add the relevant number of campaign increased
			for (Iterator<Integer> iter = campIdList.iterator(); iter.hasNext(); ) {
				int camp_id = iter.next(); 
				userDao.addCampNumToUser(username, camp_id); 
			}
		}
		String jsonPopup = "{achi_name:'" + achi.getAchi_name() + "', card_sn:'"+ achi.getCard_sn() + "'}";
		return jsonPopup;
	}
	
	/**
	 * Get achievements from application, and make the user's unlocked achievements with state of A.
	 * @param username	user name
	 * @param app_sn	application serial number
	 * @return			JSON format achievements
	 */
	public String getJsonAchisByAppsn(String username, String app_sn) {
		String jsonAchis = "]}"; 
		List<Achi> achiList = new ArrayList<Achi>(); 
		List<String> achiStringList = new ArrayList<String>(); 
		Set<Achi> achiSet = new HashSet<Achi>(); 
		
		// get user's unlocked achievements
		if (username != null) {
			achiSet = userDao.getUserByUsername(username).getAchis();
		}
		
		// let user's unlocked achievements' serial number into List
		for (Iterator<Achi> iter = achiSet.iterator(); iter.hasNext();) {
			achi = iter.next();
			achiStringList.add(achi.getAchi_sn());
		}
		
		achiList = achiDao.getAchisByAppsn(app_sn); 
		for(Iterator<Achi> iter = achiList.iterator(); iter.hasNext(); ) {
			achi = iter.next(); 
			
			String achiComp = null;
			// if the achievements sn is included in the list, make the achiComp to A
			if (achiStringList.contains(achi.getAchi_sn())) {
				achiComp = "A";
			} else {
				achiComp = "B";
			}
			jsonAchis = "{achi_sn:'" + achi.getAchi_sn() + "',achi_name:'"
					+ achi.getAchi_name() + "',achi_score:'"
					+ achi.getAchi_score() + "',achi_state:'" + achiComp + "'},"
					+ jsonAchis;
		}
		jsonAchis = "{achis:[" + jsonAchis;
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
//		System.out.println(jsonAchis); 
		return jsonAchis; 
	}

	public UserDao getUserDao() {
		return userDao;
	}

	@Resource
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	public User getUser() {
		return user;
	}

	@Resource
	public void setUser(User user) {
		this.user = user;
	}

	public Achi getAchi() {
		return achi;
	}

	@Resource
	public void setAchi(Achi achi) {
		this.achi = achi;
	}

	public AchiDao getAchiDao() {
		return achiDao;
	}

	@Resource
	public void setAchiDao(AchiDao achiDao) {
		this.achiDao = achiDao;
	}

	public BadgeDao getBadgeDao() {
		return badgeDao;
	}

	@Resource
	public void setBadgeDao(BadgeDao badgeDao) {
		this.badgeDao = badgeDao;
	}

	public CampDao getCampDao() {
		return campDao;
	}

	@Resource
	public void setCampDao(CampDao campDao) {
		this.campDao = campDao;
	}
	
}
